#include "../../common/dispatcher.hpp"
#include "../../client/requestor.hpp"
#include "../../client/rpc_caller.hpp"

void callback(const Json::Value result)
{
    ILOG("callback result: %d",result.asInt());
}

void test_basic()
{
    // 1.构造组件
    auto requestor = std::make_shared<jsonrpc::client::Requestor>();
    auto caller = std::make_shared<jsonrpc::client::RpcCaller>(requestor);
    auto dispatcher = std::make_shared<jsonrpc::Dispatcher>();

    // 2.向Dispatcher注册消息类型对应的回调
    auto rsp_callback = std::bind(&jsonrpc::client::Requestor::onResponse, requestor.get(), std::placeholders::_1, std::placeholders::_2);
    dispatcher->registerHandler<jsonrpc::BaseMessage>(jsonrpc::MType::RSP_RPC, rsp_callback); // 客户端不能使用特定的消息类型--他可能收到多种消息

    // 3.创建客户端-->建立连接
    auto message_cb = std::bind(&jsonrpc::Dispatcher::onMessage, dispatcher.get(), std::placeholders::_1, std::placeholders::_2);
    auto client = jsonrpc::ClientFactory::create("127.0.0.1", 9090);
    client->setMessageCallback(message_cb);
    client->connect();

    // 4.调用对应服务
    auto conn = client->connection();
    // 4.1同步测试
    Json::Value params, result;
    params["num1"] = 11;
    params["num2"] = 22;
    bool ret = caller->call(conn, "Add", params, result);
    if(ret != false)
    {
        std::cout << "result: " << result.asInt() << std::endl;
    }

    // 4.2异步测试
    Json::Value params2, result2;
    jsonrpc::client::RpcCaller::JsonAsyncResponse res_future;
    params2["num1"] = 33;
    params2["num2"] = 44;
    ret = caller->call(conn, "Add", params2, res_future); // 调用后立即返回, 不会阻塞, 获取的时候调用future的get(没结果阻塞)
    if(ret != false)
    {
        result2 = res_future.get();
        std::cout << "result: " << result2.asInt() << std::endl;
    }

    // 4.3回调的测试
    Json::Value params3, result3;
    params3["num1"] = 55;
    params3["num2"] = 66;
    ret = caller->call(conn, "Add", params3, callback); 
    DLOG("-----------------------")
    std::this_thread::sleep_for(std::chrono::seconds(1));
    client->shutdown();
}

int main()
{

    test_basic();
    return 0;
}